import ComponentType from "../../Config/ComponentType";
import {forEach, isArray, isBoolean, isEmpty, isFunction, isObject, isPlainObject, isString, map} from "lodash-es";
import {DataStatus} from "../../Config";
import ComboBase from "../../ComboBox/ComboBase";
import React from "react";
import {formatMoney, isValEmpty, myFormatTime, jsonParse, formatFormula, isNotEmpty} from "jh-utils";
import {Tag} from "antd";
import {FinderSelectBase} from "../../FinderSelect";
// import {previewFactor} from "../../AcctFactor/factorFinders";
// import {previewFcFactor} from "../../FcFactor/factorFinders";
// import {EmbedSelectorBase} from "../../EmbedSelector";
// import {CustEmbedSelectorBase} from "../../CustEmbedSelector";
// import TagEditorBase from "../../TagEditor/TagEditorBase";
// import { previewSalesInput } from '../../SalesInputComp/helper';

let moneyStyle = {
    whiteSpace: 'nowrap',
    // textAlign: 'right',
    overflow: 'hidden',
    textOverflow: 'ellipsis'
};

/**
 * 根据 type 渲染基础组件的值
 * @param type
 * @param props {{value, floatNum, dataIndex, selector, formatMsgByCn}}
 * @return {null|*}
 */
const baseValuePreview = (type, props) => {
    let {record, value, format, col, custEmbed, appins = {}, formatMsgByCn} = props;
    let showContent = value;
    switch (type) {
        case ComponentType.NUMBER_INPUT:
            let {floatNum} = props;
            let v = !isValEmpty(value) ? previewNumber(value, floatNum, format) : showContent;
            return (
                <div title={v || ''} style={moneyStyle}>
                    {v}
                </div>
            );
        case ComponentType.NUMBER_RANGE:
            if (isArray(value)) {
                let {0: numMin = '0', 1: numMax = '0'} = value;
                return `${numMin} ~ ${numMax}`;
            }
            break;
        case ComponentType.CALENDAR:
            if (value) {
                return myFormatTime(value, format);
            }
            break;
        case ComponentType.CHECK_BOX:
            if (isBoolean(value)) {
                showContent = isFunction(formatMsgByCn) ? formatMsgByCn(value ? '是' : '否') : (
                    value ? 'Y' : 'N'
                );
            }
            break;
        case ComponentType.COMBO_BOX:
            const {dataIndex, selector} = props;
            let tmpDataIndex = isString(dataIndex) ? dataIndex.split('.').pop() : '';
            if ('dataStatus' === tmpDataIndex) { // 数据状态
                showContent = DataStatus.formatStatus(value);
            } else {
                showContent = <ComboBase
                    selector={selector}
                    value={value}
                    readonly={true}
                />
            }
            break;
        // case ComponentType.EMBED_SELECTOR:
        //     showContent = <EmbedSelectorBase
        //         selector={props.selector}
        //         value={value}
        //         readonly={true}
        //     />;
        //     break;
        // case ComponentType.CUST_EMBED_SELECTOR:
        //     let colSelector = props.selector;
        //
        //     if (col && col.custEmbed) {
        //         colSelector = col.custEmbed.code;
        //     } else if (custEmbed) {
        //         colSelector = custEmbed.code;
        //     }
        //     showContent = <CustEmbedSelectorBase
        //         selector={colSelector}
        //         value={value}
        //         readonly={true}
        //     />;
        //     break;
        case ComponentType.ADDR_INPUT:
            return isObject(value) ? (value.name || value.code) : showContent;

        case ComponentType.OBJERCT_ENUM:
            return isObject(value) ? (value.name || value.code) : showContent;
        case ComponentType.FINDER:
            if (isObject(value)) {
                if (col && col.finderCode) {
                    return <FinderSelectBase readOnly={true}
                                             value={value}
                                             finderCode={col.finderCode}/>
                } else {
                    return value.name || value.code;
                }
            }
            break;
        case ComponentType.TAG_FINDER:
            let tmpV = [];

            if (isString(value) && !isEmpty(value)) {
                try {
                    tmpV = JSON.parse(value).data || [];
                } catch (e) {
                    tmpV = [];
                }
                tmpV = map(tmpV, (v, ind) => (
                    v && v.name ? <Tag key={v.id || `_${ind}`} style={{marginBottom: 4}}>{v.name}</Tag> : ''
                )).filter(v => v);
            }
            return tmpV;
        // case ComponentType.TAG_EDITOR:
        //     showContent = <TagEditorBase
        //         appins={appins}
        //         value={value}
        //         readonly={true}
        //     />;
        //     break;
        // case ComponentType.ACCT_FACTOR:
        //     return previewFactor(value);
        // case ComponentType.FC_FACTOR:
        //     return previewFcFactor(value);
        case ComponentType.FILTER_EDITOR:
            return isObject(value) ? (
                <div style={moneyStyle}>
                    {value.value || ''}
                </div>
            ) : '';
        case ComponentType.EXPRESSION:
            showContent = <span
                title={col.expression}>{col ? formatFormula(col.expression, record, {floatNum: col.floatNum}) : ''}</span>;
            break;
        // case ComponentType.STOCK_EX_INPUT:
        //     return previewSalesInput(value, {formatMsgByCn});
        default:
            if (isPlainObject(showContent)) {
                showContent = JSON.stringify(showContent);
            }

    }
    return showContent;
};

export const compValuePreview = (type, props) => {
    const {value} = props;
    if (type === ComponentType.GENERAL_COMPONENT && value && value.componentType) {
        return baseValuePreview(value.componentType, {...props, ...value, value: getViewValue(value)});
    } else {
        return baseValuePreview(type, props);
    }
};


/**
 * 回显数字
 * @param value
 * @param floatNum
 * @param format
 */
export function previewNumber(value, floatNum, format) {
    let val = formatMoney(value, floatNum);
    let pre = '';
    switch (format) {
        case '%': // 百分比
            let tmpV = parseFloat(value);
            val = isNaN(tmpV) ? `${formatMoney(0, floatNum)}%` : `${formatMoney(tmpV * 100, floatNum)}%`;
            break;
        case '$': // 货币
            pre = '￥';
            break;
    }
    return `${pre}${val}`;
}

export const getViewValue = (value) => {
    if (!isObject(value) || isEmpty(value)) return value;
    const type = value.componentType;
    if (ComponentType.FINDER === type || ComponentType.OBJERCT_ENUM === type) {
        return value.id > 0 ? value : null;
    } else {
        switch (type) {
            case ComponentType.NUMBER_INPUT: //√
                return value.numberVal;
            case ComponentType.NUMBER_RANGE: //√
                let numberValList = [];
                numberValList.push(value.numberVal || '');
                numberValList.push(value.numberValEnd || '');
                return numberValList;
            case ComponentType.CALENDAR: //√
                let dateValList = [];
                dateValList.push(value.dateVal || null);
                dateValList.push(value.dateValEnd || null);
                return isNotEmpty(value.dateValEnd) && dateValList || value.dateVal;
            case ComponentType.CHECK_BOX:
                return value.boolVal;
            case ComponentType.COMBO_BOX: //√
                return value.stringVal;
            case ComponentType.ADDR_INPUT: //√
                return value;
            case ComponentType.EMBED_SELECTOR:
                return jsonParse(value.stringVal);
            case ComponentType.TEXT_INPUT: //√
            case ComponentType.TEXT_AREA: //√
            case ComponentType.AUTO_COMPLETE:
            case ComponentType.CUST_EMBED_SELECTOR:
                return value.stringVal;
        }
    }
};

export const setViewValue = (config, newValue) => {
    const {componentType = '', type, finder, selector, appCode} = config;
    let newVal = {};
    if (ComponentType.FINDER === componentType || ComponentType.OBJERCT_ENUM === componentType) {
        if (isObject(newValue) && !isEmpty(newValue)) {
            newVal = {
                id: newValue.id,
                code: newValue.code,
                name: newValue.name
            };
        }
        if (ComponentType.FINDER === componentType) {
            newVal.finder = finder;
            newVal.appCode = appCode;
        }
    } else {
        switch (componentType) {
            case ComponentType.NUMBER_INPUT:
                newVal = {numberVal: newValue};
                break;
            case ComponentType.NUMBER_RANGE:
                // 判断是否为期间值
                if (isArray(newValue) && newValue.length > 1) {
                    newVal = {numberVal: newValue[0], numberValEnd: newValue[1]};
                } else {
                    newVal = {numberVal: newValue};
                }
                break;
            case ComponentType.CALENDAR:
                // 判断是否为期间值
                if (isArray(newValue) && newValue.length > 1) {
                    newVal = {dateVal: newValue[0], dateValEnd: newValue[1]};
                } else {
                    newVal = {dateVal: newValue};
                }
                break;
            case ComponentType.CHECK_BOX:
                newVal = {boolVal: newValue};
                break;
            case ComponentType.ADDR_INPUT:
                newVal = {...newValue, stringVal: newValue.name};
                break;
            case ComponentType.EMBED_SELECTOR:
                newVal = {stringVal: JSON.stringify(newValue), selector};
                break;
            case ComponentType.COMBO_BOX:
                newVal = {stringVal: newValue, selector};
                break;
            case ComponentType.TEXT_INPUT:
            case ComponentType.TEXT_AREA:
            case ComponentType.AUTO_COMPLETE:
            case ComponentType.CUST_EMBED_SELECTOR:
                newVal = {stringVal: newValue};
                break;
        }
    }

    return newVal;
};